package ml.tewas.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import ml.tewas.engine.Engine;
import ml.tewas.generator.ForceGenerator;
import ml.tewas.generator.ThreatGenerator;
import ml.tewas.util.Utilities;
import ml.tewas.weaponassignment.WeaponAssignmentUtil;

public class MainWindow extends JFrame {
	private static final int AGENT_COUNT = 2;
	private static final long serialVersionUID = 1L;
	DrawingCanvas drawingArea;
	private JMenuBar menubar;
	private JMenu fileMenu;
	private JMenuItem open;
	private JMenuItem clear;
	private JMenuItem exit;
	private Container con;
	MenuPanel menuPanel;
	
	public MainWindow() {
		init();
	}

	private void init() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		} catch (UnsupportedLookAndFeelException e1) {
			e1.printStackTrace();
		}

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("TEWAS");

		drawingArea = DrawingCanvas.getInstance();
		menuPanel = new MenuPanel();
		menubar = new JMenuBar();
		fileMenu = new JMenu("File");
		open = new JMenuItem("Open...");
		clear = new JMenuItem("Clear");
		exit = new JMenuItem("Exit");
			
		
		
		con = this.getContentPane(); // inherit the main frame
		con.add(menuPanel, BorderLayout.WEST);
		con.add(drawingArea, BorderLayout.CENTER);

		fileMenu.setMnemonic('F');
		open.setMnemonic('O');
		exit.setMnemonic('X');
		clear.setMnemonic('C');
		menubar.add(fileMenu);
		fileMenu.add(open);
		fileMenu.add(clear);
		fileMenu.add(exit);
		setJMenuBar(menubar);

		open.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				File file = openFile();
				if (file != null) {
					
				}
			}
		});

		clear.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				drawingArea.setState(DrawingCanvas.START);
				drawingArea.resetLists();
				drawingArea.resetCounts();
				drawingArea.repaint();
			}
		});

		exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				dispose();
			}
		});

		drawingArea.addMouseListener(new MouseListener() {

			public void mouseClicked(MouseEvent e) {
			}

			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
			}

			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
			}

			public void mousePressed(MouseEvent e) {
			}

			public void mouseReleased(MouseEvent e) {
			};
		});

		drawingArea.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent arg0) {
				// TODO Auto-generated method stub
			}

			public void mouseMoved(MouseEvent e) {
			};
		});

		menuPanel.setActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				drawingArea.setWorkingMode(DrawingCanvas.MANUEL_MODE);
				generateScenario();
				drawingArea.repaint();
			}

			
			
		});
		menuPanel.setPlayListener(new ActionListener(){

			public void actionPerformed(ActionEvent arg0) {
				playScenario();
			}});
		
		menuPanel.setPauseListener(new ActionListener(){

			public void actionPerformed(ActionEvent arg0) {
				if(drawingArea.getState() == DrawingCanvas.PLAY){
					drawingArea.setState(DrawingCanvas.PAUSE);
				}
			}});
		
		menuPanel.setTrainListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				new TrainThread().start();
			}

		});
		pack();
		setSize(860, 760); // set up application frame
		setResizable(false);
		setVisible(true); // add to frame and display
	}
	
	public class TrainThread extends Thread	{
		
		public void run(){
			drawingArea.resetCounts();
			drawingArea.setState(DrawingCanvas.SCENARIO_END);
			int trainCount = menuPanel.getTrainCount();
			for (int i = 0; i <= trainCount; ) {
				if (drawingArea.getState() == DrawingCanvas.SCENARIO_END) {
					if(i == trainCount){
						displayScenarioResultsOnPanel();
						return;
					}
					i++;
					displayScenarioResultsOnPanel();
					drawingArea.setWorkingMode(DrawingCanvas.TRAIN_MODE);
					generateScenario();
					playScenario();
				}
			}
			displayScenarioResultsOnPanel();
			
		}

		private void displayScenarioResultsOnPanel() {
			int lost = drawingArea.getAgentLost();
			int won = drawingArea.getAgentWin();
			menuPanel.setTrainResult("" + (lost + won), "" + won,
					"" + lost);
		}
	}
	
	private void generateScenario() {
		drawingArea.setState(DrawingCanvas.INIT);
		int numberOfThreats = menuPanel.getThreatNumber();
		float learningRate = menuPanel.getLearningRate();
		Utilities.LEARNING_RATE = learningRate;
		WeaponAssignmentUtil.COORDINATAION = menuPanel.getCoordination();
		ThreatGenerator threatGenerator = new ThreatGenerator();
		ForceGenerator  forceGenerator = new ForceGenerator(numberOfThreats);
		drawingArea.resetLists();			
		boolean isTraining = drawingArea.getWorkingMode() == DrawingCanvas.TRAIN_MODE;
		drawingArea.setForceList(forceGenerator.generateForces(AGENT_COUNT, isTraining));
		drawingArea.setThreatList(threatGenerator.generateThreats(numberOfThreats));
		drawingArea.setState(DrawingCanvas.READY);
	}
	
	private void playScenario() {
		int state = drawingArea.getState();
		if(state == DrawingCanvas.READY){
			drawingArea.setState(DrawingCanvas.PLAY);
			Engine engine = new Engine(menuPanel.getSpeed());
			engine.start();
		} else if(state == DrawingCanvas.PAUSE){
			drawingArea.setState(DrawingCanvas.PLAY);
		} 
	}
	private File openFile() {
		File file = null;
		JFileChooser fc = new JFileChooser();

		int returnVal = fc.showOpenDialog(MainWindow.this);
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			file = fc.getSelectedFile();
		} else {
			System.out.println("Open command cancelled by user.");
		}

		return file;
	}

	public static void main(String[] args) {
		new MainWindow();
	}
}
